home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 February / EnigmA AMIGA RUN 04 (1996)(G.R. Edizioni)(IT)[!][issue 1996-02][Skylink CD III].iso / earcd / assembler / progasm1.lha / SORGENTI2 / LEZIONE6o.s < prev    next >
Text File  |  1994-07-16  |  15KB  |  429 lines

  1.  
  2. ; Lezione6o.s        SCORRIMENTO A DESTRA E SINISTRA DI UN PLAYFIELD PIU'
  3. ;            GRANDE DELLO SCHERMO (qua largo 640 pixel)
  4. ;            Tasto destro per bloccare lo scroll
  5.  
  6.     SECTION    CiriCop,CODE
  7.  
  8. Inizio:
  9.     move.l    4.w,a6        ; Execbase
  10.     jsr    -$78(a6)    ; Disable
  11.     lea    GfxName(PC),a1    ; Nome lib
  12.     jsr    -$198(a6)    ; OpenLibrary
  13.     move.l    d0,GfxBase
  14.     move.l    d0,a6
  15.     move.l    $26(a6),OldCop    ; salviamo la vecchia COP
  16.  
  17. ; Attenzione! Per "centrare" l'immagine occorre puntare 2 bytes piu' indietro
  18. ; facendo scorrere in avanti la PIC di 16 pixel, infatti la figura comincia
  19. ; 16 pixel piu' indietro grazie al DDFSTART (zona "coperta" dove avviene
  20. ; l'errore di visualizzazione da nascondere).
  21.  
  22.     MOVE.L    #BITPLANE-2,d0    ; in d0 mettiamo l'indirizzo del bitplane -2,
  23.                 ; ossia -16 pixel, in quanto i "primi" 16 pixel
  24.                 ; sono "coperti" e dobbiamo "saltarli",
  25.                 ; spostando la PIC in avanti, appunto, di 16
  26.                 ; pixel
  27.     LEA    BPLPOINTERS,A1    ; puntatori nella COPPERLIST
  28.     move.w    d0,6(a1)    ; copia la word BASSA dell'indirizzo del plane
  29.     swap    d0        ; scambia le 2 word di d0 (es: 1234 > 3412)
  30.     move.w    d0,2(a1)    ; copia la word ALTA dell'indirizzo del plane
  31.  
  32.     bsr.w    print        ; Stampa le linee di testo sul playfield
  33.                 ; largo 640 pixel (80 byte per linea)
  34.  
  35.     move.l    #COPPERLIST,$dff080    ; nostra COP
  36.     move.w    d0,$dff088        ; START COP
  37.     move.w    #0,$dff1fc        ; NO AGA!
  38.     move.w    #$c00,$dff106        ; NO AGA!
  39.  
  40. mouse:
  41.     cmpi.b    #$ff,$dff006    ; Linea 255?
  42.     bne.s    mouse
  43.  
  44.     btst    #2,$dff016    ; Tasto destro?
  45.     beq.w    Aspetta        ; Se si, non scrollare
  46.  
  47.     bsr.w    MEGAScrolla    ; Scorrimento orizzontale di una figura larga
  48.                 ; 640 pixel in uno schermo largo 320 pixel.
  49.  
  50. Aspetta:
  51.     cmpi.b    #$ff,$dff006    ; linea 255?
  52.     beq.s    Aspetta
  53.  
  54.     btst    #6,$bfe001    ; mouse premuto?
  55.     bne.s    mouse
  56.  
  57.     move.l    OldCop(PC),$dff080    ; Puntiamo la cop di sistema
  58.     move.w    d0,$dff088        ; facciamo partire la vecchia cop
  59.  
  60.     move.l    4.w,a6
  61.     jsr    -$7e(a6)    ; Enable
  62.     move.l    gfxbase(PC),a1
  63.     jsr    -$19e(a6)    ; Closelibrary
  64.     rts
  65.  
  66. ;    Dati
  67.  
  68. GfxName:
  69.     dc.b    "graphics.library",0,0
  70.  
  71. GfxBase:
  72.     dc.l    0
  73.  
  74. OldCop:
  75.     dc.l    0
  76.  
  77. ; La routine Megascrolla serve solamente ad eseguire 320 volte la routine gia'
  78. ; vista "Destra:", dopodiche' eseguire 320 volte la routine "Sinistra:" per
  79. ; riportare la figura alla posizione iniziale, di qua il ciclo riparte ecc.
  80. ; Per tenere il conto del numero di volte che ha eseguito "Destra:" o
  81. ; "Sinistra:" utilizza la word "Contavolte" a cui addiziona "1" ogni FRAME;
  82. ; essendo lo schermo video largo 320 pixel e la figura in memoria larga 640,
  83. ; per scorrerla occorrera' spostarsi di 320 pixel:
  84. ;
  85. ; All'inizio:
  86. ;     _______________________________
  87. ;    |        |        |
  88. ;    | schermo video |        |
  89. ;    | <-   320   -> |        |
  90. ;    |        |        |
  91. ;    | <- immagine in memoria 640 -> |
  92. ;    |        |        |
  93. ;    |        |        |
  94. ;     -------------------------------
  95. ;
  96. ; Quando abbiamo "scrollato" di 320 pixel a Destra:
  97. ;     _______________________________
  98. ;    |        |        |
  99. ;    |         | schermo video |
  100. ;    |        | <-   320   -> |
  101. ;    |        |        |
  102. ;    | <- immagine in memoria 640 -> |
  103. ;    |        |        |
  104. ;    |        |        |
  105. ;     -------------------------------
  106. ;
  107. ; Poi altri 320 pixel verso sinistra e torniamo a vedere i primi 320 pixel
  108. ; della figura larga 640.
  109. ; Tramite il bit 1 della word DestSinFlag viene segnalato se e' necessario
  110. ; andare verso destra o verso sinistra. Per scambiare il valore del bit, da
  111. ; ZERO ad UNO o da UNO a ZERO e' usata l'istruzione BCHG, ossia BIT CHANGE,
  112. ; gia' vista in un'altro listato.
  113.  
  114. MEGAScrolla:
  115.     addq.w    #1,ContaVolte    ; Segnamo una esecuzione in piu'
  116.     cmp.w    #320,ContaVolte    ; Siamo a 320?
  117.     bne.S    MuoviAncora    ; Se non ancora, sposta ancora
  118.     BCHG.B    #1,DestSinFlag    ; Se siamo a 320, invece, cambia direzione
  119.     CLR.w    ContaVolte    ; di scorrimento e azzera "ContaVolte"
  120.     rts
  121.  
  122. MuoviAncora:
  123.     BTST    #1,DestSinFlag    ; Dobbiamo andare a destra o a sinistra?
  124.     BEQ.S    VaiSinistra
  125.     bsr.s    Destra        ; Scorri un pixel verso destra
  126.     rts
  127.  
  128. VaiSinistra:
  129.     bsr.s    Sinistra    ; Scorri un pixel verso sinistra
  130.     rts
  131.  
  132. ; Questa word conta quante volte ci siamo spostati a Destra o a Sinistra
  133.  
  134. ContaVolte:
  135.     DC.W    0
  136.  
  137. ; Quando il bit 1 di DestSinFlag e' a ZERO la routine scorre a Sinistra, se
  138. ; e' ad 1 scorre a Destra.
  139.  
  140. DestSinFlag:
  141.     DC.W    0
  142.  
  143. ; Questa routine fa scorrere a destra un bitplane agendo sul BPLCON1 e sui
  144. ; puntatori ai bitplanes in copperlist. MIOBPCON1 e' il byte del BPLCON1.
  145.  
  146. Destra:
  147.     CMP.B    #$ff,MIOBPCON1    ; siamo arrivati al massimo scorrimento? (15)
  148.     BNE.s    CON1ADDA    ; se non ancora, scorri in avanti di 1
  149.                 ; con il BPLCON1
  150.  
  151.     LEA    BPLPOINTERS,A1    ; Con queste 4 istruzioni preleviamo dalla
  152.     move.w    2(a1),d0    ; copperlist l'indirizzo dove sta puntando
  153.     swap    d0        ; attualmente il $dff0e0 e lo poiniamo in d0
  154.     move.w    6(a1),d0
  155.  
  156.     subq.l    #2,d0        ; punta 16 bit piu' indietro ( la PIC scorre
  157.                 ; verso destra di 16 pixel)
  158.     clr.b    MIOBPCON1    ; azzera lo scroll hardware BPLCON1 ($dff102)
  159.                 ; infatti abbiamo "saltato" 16 pixel con il
  160.                 ; bitplane pointer, ora dobbiamo ricominciare
  161.                 ; da zero con il $dff102 per scattare a
  162.                 ; destra di un pixel alla volta.
  163.  
  164.     move.w    d0,6(a1)    ; copia la word BASSA dell'indirizzo del plane
  165.     swap    d0        ; scambia le 2 word di d0 (es: 1234 > 3412)
  166.     move.w    d0,2(a1)    ; copia la word ALTA dell'indirizzo del plane
  167.     rts
  168.  
  169. CON1ADDA:
  170.     add.b    #$11,MIOBPCON1    ; scorri in avanti di 1 pixel
  171.     rts
  172.  
  173. ;    Routine che sposta a sinistra in modo analogo:
  174.  
  175. Sinistra:
  176.     TST.B    MIOBPCON1    ; siamo arrivati al minimo scorrimento? (00)
  177.     BNE.s    CON1SUBBA    ; se non ancora, scorri indietro di 1
  178.                 ; con il BPLCON1
  179.  
  180.     LEA    BPLPOINTERS,A1    ; Con queste 4 istruzioni preleviamo dalla
  181.     move.w    2(a1),d0    ; copperlist l'indirizzo dove sta puntando
  182.     swap    d0        ; attualmente il $dff0e0 e lo poiniamo in d0
  183.     move.w    6(a1),d0
  184.  
  185.     addq.l    #2,d0        ; punta 16 bit piu' avanti ( la PIC scorre
  186.                 ; verso sinistra di 16 pixel)
  187.     move.b    #$FF,MIOBPCON1    ; scroll hardware a 15 - BPLCON1 ($dff102)
  188.  
  189.     move.w    d0,6(a1)    ; copia la word BASSA dell'indirizzo del plane
  190.     swap    d0        ; scambia le 2 word di d0 (es: 1234 > 3412)
  191.     move.w    d0,2(a1)    ; copia la word ALTA dell'indirizzo del plane
  192.     rts
  193.  
  194. CON1SUBBA:
  195.     sub.b    #$11,MIOBPCON1    ; scorri indietro di 1 pixe
  196.     rts
  197.  
  198.  
  199.  
  200. ;    Routine che stampa caratteri larghi 8x8 pixel (su schermo HIRES)
  201.  
  202. PRINT:
  203.     LEA    TESTO(PC),A0    ; Indirizzo del testo da stampare in a0
  204.     LEA    BITPLANE,A3    ; Indirizzo del bitplane destinazione in a3
  205.     MOVEQ    #25-1,D3    ; NUMERO RIGHE DA STAMPARE: 25
  206. PRINTRIGA:
  207.     MOVEQ    #80-1,D0    ; NUMERO COLONNE PER RIGA: 80 (hires!)
  208. PRINTCHAR2:
  209.     MOVEQ    #0,D2        ; Pulisci d2
  210.     MOVE.B    (A0)+,D2    ; Prossimo carattere in d2
  211.     SUB.B    #$20,D2        ; TOGLI 32 AL VALORE ASCII DEL CARATTERE, IN
  212.                 ; MODO DA TRASFORMARE, AD ESEMPIO, QUELLO
  213.                 ; DELLO SPAZIO (che e' $20), in $00, quello
  214.                 ; DELL'ASTERISCO ($21), in $01...
  215.     MULU.W    #8,D2        ; MOLTIPLICA PER 8 IL NUMERO PRECEDENTE,
  216.                 ; essendo i caratteri alti 8 pixel
  217.     MOVE.L    D2,A2
  218.     ADD.L    #FONT,A2    ; TROVA IL CARATTERE DESIDERATO NEL FONT...
  219.  
  220.                 ; STAMPIAMO IL CARATTERE LINEA PER LINEA
  221.     MOVE.B    (A2)+,(A3)    ; stampa LA LINEA 1 del carattere
  222.     MOVE.B    (A2)+,80(A3)    ; stampa LA LINEA 2  " "
  223.     MOVE.B    (A2)+,80*2(A3)    ; stampa LA LINEA 3  " "
  224.     MOVE.B    (A2)+,80*3(A3)    ; stampa LA LINEA 4  " "
  225.     MOVE.B    (A2)+,80*4(A3)    ; stampa LA LINEA 5  " "
  226.     MOVE.B    (A2)+,80*5(A3)    ; stampa LA LINEA 6  " "
  227.     MOVE.B    (A2)+,80*6(A3)    ; stampa LA LINEA 7  " "
  228.     MOVE.B    (A2)+,80*7(A3)    ; stampa LA LINEA 8  " "
  229.  
  230.     ADDQ.w    #1,A3        ; A1+1, avanziamo di 8 bit (PROSSIMO CARATTERE)
  231.  
  232.     DBRA    D0,PRINTCHAR2    ; STAMPIAMO D0 (80) CARATTERI PER RIGA
  233.  
  234.     ADD.W    #80*7,A3    ; ANDIAMO A CAPO
  235.  
  236.     DBRA    D3,PRINTRIGA    ; FACCIAMO D3 RIGHE
  237.  
  238.     RTS
  239.  
  240.  
  241.         ; numero caratteri per linea: 80, dunque 2 di queste da 40!
  242. TESTO:         ;          1111111111222222222233333333334
  243.          ;     1234567890123456789012345678901234567890
  244.     dc.b    '   PRIMA RIGA  IN HIRES 640 PIXEL DI LAR' ; 1a \ PRIMA RIGA
  245.     dc.b    'GHEZZA!  -- -- --   SEMPRE LA PRIMA RIGA' ; 1b /
  246.     dc.b    '                SECONDA RIGA            ' ; 2  \ SECONDA RIGA
  247.     dc.b    'ANCORA SECONDA RIGA                     ' ;    /
  248.     dc.b    '     /\  /                              ' ; 3
  249.     dc.b    '                                        ' ;
  250.     dc.b    '    /  \/                               ' ; 4
  251.     dc.b    '                                        ' ;
  252.     dc.b    '                                        ' ; 5
  253.     dc.b    '                                        ' ;
  254.     dc.b    '        SESTA RIGA                      ' ; 6
  255.     dc.b    '                        FINE SESTA RIGA ' ;
  256.     dc.b    '                                        ' ; 7
  257.     dc.b    '                                        ' ;
  258.     dc.b    '                                        ' ; 8
  259.     dc.b    '                                        ' ;
  260.     dc.b    'FABIO CIUCCI COMMUNICATION INTERNATIONAL' ; 9
  261.     dc.b    ' MARKETING TRUST TRADEMARK COPYRIGHTED  ' ;
  262.     dc.b    '                                        ' ; 10
  263.     dc.b    '                                        ' ;
  264.     dc.b    '   1234567890 !@#$%^&*()_+|\=-[]{}      ' ; 11
  265.     dc.b    '   PROVE TECNICHE DI TRASMISSIONE       ' ;
  266.     dc.b    '                                        ' ; 12
  267.     dc.b    '                                        ' ;
  268.     dc.b    '     LA PALINGENETICA OBLITERAZIONE DELL' ; 13
  269.     dc.b    "'IO TRASCENDENTALE CHE SI IMMEDESIMA    " ;
  270.     dc.b    '                                        ' ; 14
  271.     dc.b    '                                        ' ;
  272.     dc.b    '                                        ' ; 15
  273.     dc.b    '                                        ' ;
  274.     dc.b    '  Nel mezzo del cammin di nostra vita   ' ; 16
  275.     dc.b    '                                        ' ;
  276.     dc.b    '                                        ' ; 17
  277.     dc.b    '                                        ' ;
  278.     dc.b    '    Mi RitRoVaI pEr UnA sELva oScuRa    ' ; 18
  279.     dc.b    '                                        ' ;
  280.     dc.b    '                                        ' ; 19
  281.     dc.b    '                                        ' ;
  282.     dc.b    '    CHE LA DIRITTA VIA ERA SMARRITA     ' ; 20
  283.     dc.b    '                                        ' ;
  284.     dc.b    '                                        ' ; 21
  285.     dc.b    '                                        ' ;
  286.     dc.b    '  AHI Quanto a DIR QUAL ERA...          ' ; 22
  287.     dc.b    '                                        ' ;
  288.     dc.b    '                                        ' ; 23
  289.     dc.b    '                                        ' ;
  290.     dc.b    '                                        ' ; 24
  291.     dc.b    '                                        ' ;
  292.     dc.b    ' C:\>_                                  ' ; 25
  293.     dc.b    '                                        ' ;
  294.     dc.b    '                                        ' ; 26
  295.     dc.b    '                                        ' ;
  296.  
  297.     EVEN
  298.  
  299.  
  300.  
  301.     SECTION    GRAPHIC,DATA_C
  302.  
  303. COPPERLIST:
  304.     dc.w    $120,0,$122,0,$124,0,$126,0,$128,0 ; SPRITE
  305.     dc.w    $12a,0,$12c,0,$12e,0,$130,0,$132,0
  306.     dc.w    $134,0,$136,0,$138,0,$13a,0,$13c,0
  307.     dc.w    $13e,0
  308.  
  309.     dc.w    $8e,$2c81    ; DiwStrt
  310.     dc.w    $90,$2cc1    ; DiwStop
  311.     dc.w    $92,$30        ; DdfStart (modificato per SCROLL)
  312.     dc.w    $94,$d0        ; DdfStop
  313.     dc.w    $102        ; BplCon1
  314.     dc.b    0        ; byte "alto" inutilizzato del $dff102
  315. MIOBPCON1:
  316.     dc.b    0        ; byte "basso" utilizzato del $dff102
  317.     dc.w    $104,0        ; BplCon2
  318.     dc.w    $108,40-2    ; Bpl1Mod (40 per la figura larga 640, il -2
  319.     dc.w    $10a,40-2    ; Bpl2Mod (per bilanciare il DDFSTART
  320.  
  321.             ; 5432109876543210
  322.     dc.w    $100,%0001001000000000    ; bit 12 - 1 bitplane LOWRES
  323.  
  324. BPLPOINTERS:
  325.     dc.w $e0,0,$e2,0    ;primo    bitplane
  326.  
  327.     dc.w    $180,$103    ; color0 - SFONDO
  328.     dc.w    $182,$4ff    ; color1 - SCRITTE
  329.  
  330.     dc.w    $FFFF,$FFFE    ; Fine della copperlist
  331.  
  332. ;    Il FONT caratteri 8x8
  333.  
  334. FONT:
  335. ;    incbin    "metal.fnt"
  336. ;    incbin    "normal.fnt"
  337.     incbin    "nice.fnt"
  338.  
  339.  
  340.     SECTION    MIOPLANE,BSS_C
  341.  
  342. BITPLANE:
  343.     ds.b    80*256    ; un bitplane largo 640x256 (come l'HIRES)
  344.  
  345.     end
  346.  
  347. In questo listato l'unica vera novita' sta nel fatto che scorriamo una figura
  348. piu' grande dello schermo anziche' una grande 320 pixel.
  349. Innanzitutto quando lo schermo e' in LOWRES con valori DDFSTART/STOP normali
  350. il modulo "automatico" e' 40, ossia l'immagine viene considerata fatta di
  351. linee di 40 bytes. Se invece abbiamo in memoria una figura larga 640 pixel,
  352. come in questo caso, dobbiamo cambiare il modulo. Infatti il fatto che la
  353. figura in memoria e' piu' grande non interessa al Copper, il quale visualizza
  354. come sempre uno schermo in LOWRES con modulo 40. Noi possiamo pero' cambiare
  355. il modulo tramite i registri BPL1MOD e BPL2MOD: il modulo viene aggiunto al
  356. modulo corrente, che e' 40, dunque bastera' un:
  357.  
  358.     dc.w    $108,40        ; Bpl1Mod (40 per la figura larga 640)
  359.     dc.w    $10a,40        ; Bpl2Mod
  360.  
  361. Per far "saltare" alla fine di ogni linea di 320 pixel (40 bytes) i 40 bytes
  362. che sono "fuori video", facendo continuare la visualizzazione dall'inizio della
  363. linea seguente:
  364.  
  365.      40 bytes      40 bytes (saltati ogni volta col modulo = 40)
  366.      _______________________________
  367.     |        |        |
  368.     | schermo video |        |
  369.     | <-   320   -> |        |
  370.     |        |        |
  371.     | <- immagine in memoria 640 -> |
  372.     |        |        |
  373.     |        |        |
  374.      -------------------------------
  375.  
  376. Ora, avendo visualizzato la parte Destra della figura larga 640 pixel su uno
  377. schermo largo 320 SEMPLICEMENTE mettendo i moduli a 40, dobbiamo fare la
  378. stessa modifica dell'esempio Lezione6n.s per "nascondere" i primi 16 pixel
  379. dove avviene l'errore di visualizzazione a cusa dello scroll.
  380. Dobbiamo allora far partire lo schermo 16 pixel prima modificando il DDFSTART:
  381.  
  382.     dc.w    $92,$30            ; DDFSTART = $30 (schermo che parte
  383.                     ; 16 pixel prima, allungandosi a
  384.                     ; 42 bytes per linea, 336 pixel di
  385.                     ; larghezza, ma il DIWSTART "nasconde"
  386.                     ; questi primi 16 pixel con l'errore.
  387.  
  388. E, in quanto abbiamo allargato lo schermo facendolo andare "a capo" ogni 42
  389. bytes anziche' 40, e' necessario bilanciare sottraendo 2 ai moduli, che
  390. nel nostro caso erano a 40, e andranno a 38:
  391.  
  392.     dc.w    $108,40-2    ; Bpl1Mod (40 per la figura larga 640, il -2
  393.     dc.w    $10a,40-2    ; Bpl2Mod (per bilanciare il DDFSTART
  394.  
  395. In fondo non si puo' dire che uno scroll di questo tipo e' "difficile", l'unica
  396. difficolta' sta nel ricordarsi di sistemare bene MODULI/DDFSTART/INDIRIZZO DEL
  397. BITPLANE. Infatti c'e' anche un'altra "novita'" rispetto a Lezione6n.s:
  398.  
  399. ; Attenzione! Per "centrare" l'immagine occorre puntare 2 bytes piu' indietro
  400. ; facendo scorrere in avanti la PIC di 16 pixel, infatti la figura comincia
  401. ; 16 pixel piu' indietro grazie al DDFSTART (zona "coperta" dove avviene
  402. ; l'errore di visualizzazione da nascondere).
  403.  
  404.     MOVE.L    #BITPLANE-2,d0    ; in d0 mettiamo l'indirizzo del bitplane -2,
  405.                 ; ossia -16 pixel, in quanto i "primi" 16 pixel
  406.                 ; sono "coperti" e dobbiamo "saltarli",
  407.                 ; spostando la PIC in avanti, appunto, di 16
  408.                 ; pixel
  409.  
  410. Infatti abbiamo "nascosto" i primi 16 pixel, dunque nasconderemmo i primi 2
  411. caratteri del testo, (8pixel ciascuno*2=16 pixel). Invece "spostando" la figura
  412. in avanti di 16 pixel vediamo correttamente anche i primi 16 pixel e la figura
  413. appare centrata, non spostata verso sinistra di 16 pixel come in Lezione6n.s.
  414. Provate a togliere il -2 dal "MOVE.L #BITPLANE-2,d0" e mettete un ; alla
  415. routine
  416.  
  417. ;    bsr.w    MEGAScrolla
  418.  
  419. in modo da avere una figura FERMA e noterete che i primi 16 pixel mancano, e
  420. ce ne sono 2 in piu' a destra, ossia la figura parte 16 pixel prima del normale
  421. Per verificare cio', "scopriamo" i primi 16 pixel:
  422.  
  423.     dc.w    $8e,$2c71    ; DiwStrt ($81-16=$71)
  424.  
  425. Ecco li' i primi 16 pixel "spariti!". Rimettete a posto il -2 e togliete il ;
  426. dalla routine lasciando i primi 16 pixel "scoperti" e vedrete come l'errore
  427. fatidico dello scroll avviene in sordina "dietro le quinte".
  428.  
  429.